﻿namespace Beetle.Clients
{
    using Beetle;
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Threading;

    public class TcpSyncPool
    {
        private Dictionary<string, TcpSyncNode> _field_a;
        private List<TcpSyncNode> _field_b;
        [ThreadStatic]
        private static TcpSyncPool_a _field_c;
        [ThreadStatic]
        private static object _field_d;

        public TcpSyncPool()
        {
            this._field_a = new Dictionary<string, TcpSyncNode>(0x10);
            this._field_b = new List<TcpSyncNode>();
        }

        public TcpSyncPool(string section)
        {
            this._field_a = new Dictionary<string, TcpSyncNode>(0x10);
            this._field_b = new List<TcpSyncNode>();
            PoolSection section2 = (PoolSection) ConfigurationManager.GetSection(section);
            if (section2 == null)
            {
                throw NetTcpException.ClientPoolSectionNotFound(section);
            }
            if (section != null)
            {
                foreach (ServerNode node in section2.Servers)
                {
                    this.AddNode(node.Name, node.Host, node.Port, node.MaxConnections, node.DetectTime);
                }
            }
        }

        public void AddNode(string name, string host, int port, int maxconnections)
        {
            this.AddNode(name, host, port, maxconnections, 30);
        }

        public void AddNode(string name, string host, int port, int maxconnections, int detectTime)
        {
            TcpSyncNode item = new TcpSyncNode(host, port, maxconnections) {
                Name = name,
                DetectTime = detectTime
            };
            this.Nodes.Add(item);
            this._field_a.Add(name, item);
        }

        public void Connect<T>(int count) where T: ITcpSyncChannel, new()
        {
            foreach (TcpSyncNode node in this.Nodes)
            {
                node.Connect<T>();
            }
            Thread.Sleep(0x3e8);
        }

        public virtual TcpSyncNode GetNode()
        {
            if (_field_c == null)
            {
                _field_c = new TcpSyncPool_a();
            }
            if (this._field_b.Count != 0)
            {
                for (int i = 0; i <= this._field_b.Count; i++)
                {
                    _field_c._field_a++;
                    if (_field_c._field_a >= this._field_b.Count)
                    {
                        _field_c._field_a = 0;
                    }
                    TcpSyncNode node = this._field_b[_field_c._field_a];
                    if (node.Status == NodeStatus.Error)
                    {
                        node.CheckState();
                    }
                    else if (node.Detect())
                    {
                        return node;
                    }
                }
            }
            return null;
        }

        public virtual TcpSyncNode GetNode(params string[] names)
        {
            TcpSyncNode node = null;
            for (int i = 0; i < names.Length; i++)
            {
                if (this._field_a.TryGetValue(names[i], out node))
                {
                    if (node.Status == NodeStatus.Error)
                    {
                        node.CheckState();
                    }
                    else if (node.Detect())
                    {
                        return node;
                    }
                }
            }
            return null;
        }

        protected virtual object OnSend(object message)
        {
            TcpSyncNode node = this.GetNode();
            if ((node == null) || (node.Status == NodeStatus.Error))
            {
                throw NetTcpException.ConnectionIsNotAvailable();
            }
            return node.Send(message);
        }

        protected virtual object OnSend(object message, params string[] nodes)
        {
            TcpSyncNode node = this.GetNode(nodes);
            if ((node == null) || (node.Status == NodeStatus.Error))
            {
                throw NetTcpException.ConnectionIsNotAvailable();
            }
            return node.Send(message);
        }

        public RESULT Send<RESULT>(object message)
        {
            return (RESULT) this.OnSend(message);
        }

        public object Send(object message)
        {
            return this.OnSend(message);
        }

        public object Send(object message, params string[] nodes)
        {
            return this.OnSend(message, nodes);
        }

        public RESULT Send<RESULT>(object message, params string[] nodes)
        {
            return (RESULT) this.OnSend(message, nodes);
        }

        public IList<TcpSyncNode> Nodes
        {
            get
            {
                return this._field_b;
            }
        }

        public static object UserToken
        {
            get
            {
                return _field_d;
            }
            set
            {
                _field_d = value;
            }
        }

        private class TcpSyncPool_a
        {
            public int _field_a;
        }
    }
}

